package com.ruoyi.activiti.controller;

import com.ruoyi.activiti.domain.CustomProcess;
import com.ruoyi.activiti.domain.HistoryTask;
import com.ruoyi.activiti.domain.ProcessHistory;
import com.ruoyi.activiti.service.ICustomProcessService;
import com.ruoyi.activiti.service.IProcessService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api("自定义流程引擎")
@RestController
@RequestMapping("/custom/process")
@AllArgsConstructor
public class CustomProcessController extends BaseController {
    @Autowired
    private ICustomProcessService customProcessService;
    @Autowired
    private IProcessService processService;

    @ApiOperation("获取定义的流程列表")
    @PostMapping("/list")
    public TableDataInfo list(@RequestBody CustomProcess process)
    {
        startPage();
        List<CustomProcess> list = customProcessService.selectList(process);
        return getDataTable(list);
    }
    @ApiOperation("保存流程")
    @PostMapping("/saveProcess")
    public AjaxResult saveProcess(@RequestBody CustomProcess process){
        customProcessService.saveProcess(process);
        return AjaxResult.success();
    }
    @Log(title = "处理流程引擎发过来的任务", businessType = BusinessType.INSERT)
    @ApiOperation("处理流程引擎发过来的任务")
    @PostMapping("/processTask")
    public AjaxResult processTask(@RequestBody Map<String,Object> params){
        customProcessService.processTask(params);
        return AjaxResult.success();
    }
    @ApiOperation("更新流程")
    @PostMapping("/updateProcess")
    public AjaxResult updateProcess(@RequestBody CustomProcess process){
        customProcessService.updateProcess(process);
        return AjaxResult.success();
    }
    @ApiOperation("删除流程")
    @GetMapping("/delete")
    public AjaxResult delete(Long id) {
        customProcessService.deleteProcess(id);
        return AjaxResult.success();
    }
    @ApiOperation("通过主键获取流程详情")
    @GetMapping("/getProcessInfo")
    public AjaxResult getProcessInfo(Long id) {
        CustomProcess process = customProcessService.selectById(id);
        return AjaxResult.success(process);
    }
    @ApiOperation("部署流程")
    @GetMapping("/deploy")
    public AjaxResult deploy(Long id) {
        customProcessService.deploy(id);
        return AjaxResult.success();
    }
    @ApiOperation("展示历史")
    @GetMapping("/listHistory")
    public AjaxResult listHistory(String procDefId) {
        List<ProcessHistory> list = customProcessService.listHistory(procDefId);
        return AjaxResult.success(list);
    }
    @ApiOperation("展示历史通过流程实例id查询")
    @GetMapping("/listHistoryForInst")
    public AjaxResult listHistoryForInst(String instanceId) {
        List<ProcessHistory> list = customProcessService.listHistoryForInstanceId(instanceId);
        return AjaxResult.success(list);
    }
    @ApiOperation("展示任务历史通过流程实例id查询")
    @GetMapping("/listTaskHistory")
    public AjaxResult listTaskHistory(String instanceId) {
        List<HistoryTask> list = customProcessService.listTaskHistory(instanceId);
        return AjaxResult.success(list);
    }
    @ApiOperation("展示历史通过流程实例id查询-给图像展示使用的")
    @GetMapping("/listHistoryGraphForInst")
    public AjaxResult listHistoryGraphForInst(String instanceId) {
        List<ProcessHistory> list = customProcessService.listHistoryForInstanceId(instanceId);
        processList(list);
        return AjaxResult.success(list);
    }

    /**
     * 处理历史审批记录，主要是为了x6图形回显使用的，因为审批记录中一个任务可能会出现多次。
     * 如果一个任务出现了多次，并且存在运行状态的任务，那么就把成功状态的任务都删除，这样x6凸显展示的时候，就会展示运行中的动态效果
     * @param list
     */
    private void processList(List<ProcessHistory> list){
        if(CollectionUtils.isEmpty(list)) {
            return;
        }
        Map<String, Long> groupMap = list.stream().collect(Collectors.groupingBy(item -> item.getActId(), Collectors.counting()));
        List<ProcessHistory> removeList = new ArrayList<>();
        for (Map.Entry<String, Long> entry : groupMap.entrySet()) {
            if(entry.getValue() > 1) {
                List<ProcessHistory> successList = list.stream().filter(item -> item.getActId().equals(entry.getKey()) && item.getStatus().equals("success"))
                        .collect(Collectors.toList());
                List<ProcessHistory> runningList = list.stream().filter(item -> item.getActId().equals(entry.getKey()) && item.getStatus().equals("running"))
                        .collect(Collectors.toList());
                if(runningList.size() > 0) {
                    removeList.addAll(successList);
                }
            }
        }
        list.removeAll(removeList);
    }
    @ApiOperation("获取流程实例对应的x6图形数据")
    @GetMapping("/getX6GraphData")
    public AjaxResult getX6GraphData(String instanceId) {
        String graphData = customProcessService.getGraphDataForInstance(instanceId);
        return AjaxResult.success(graphData);
    }
    @ApiOperation("提交申请")
    @PostMapping("/submit")
    public AjaxResult submitApply(@RequestBody Map<String,Object> map) throws Exception {
        Map<String,Object> vars = (Map<String, Object>) map.get("data");
        String key = (String) map.get("key");
        processService.submitApply(key,vars);
        return AjaxResult.success();
    }
}
